#include <iostream>
using namespace std;

class L1Provider {
public:
    virtual void L1Service() = 0;
};

class L2Provider {
public:
    virtual void L2Service() = 0;
    void setLowerLayer(L1Provider *l1) {level1=l1;}
protected:
    L1Provider *level1;
};

class L3Provider {
public:
    virtual void L3Service() = 0;
    void setLowerLayer(L2Provider *l2) {level2=l2;}
protected:
    L2Provider *level2;
};

class DataLink : public L1Provider {
public:
    virtual void L1Service()
    {
        cout << "L1Service doing its job" << endl;
    }
};

class Transport : public L2Provider {
public:
    virtual void L2Service()
    {
        cout << "L2Service starting its job" << endl;
        level1->L1Service();
        cout << "L2Service finishing its job" << endl;
    }
};

class Session : public L3Provider {
public:
    virtual void L3Service()
    {
        cout << "L3Service starting its job" << endl;
        level2->L2Service();
        cout << "L3Service finishing its job" << endl;
    }
};

int main()
{
    DataLink datalink;
    Transport transport;
    Session session;

    transport.setLowerLayer(&datalink);
    session.setLowerLayer(&transport);

    session.L3Service();

    return 0;
}
